package no.ntnu.fp.gui.dialog;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.sql.Date;
import java.sql.Time;
import java.text.DateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;

import no.ntnu.fp.gui.EventDispatcher;
import no.ntnu.fp.gui.events.MeetingRoomsRequestedEvent;
import no.ntnu.fp.gui.mainFrame.ModelListenerProvider;
import no.ntnu.fp.model.Appointment;
import no.ntnu.fp.model.MeetingRoom;
import no.ntnu.fp.model.events.DialogRoomScheduleChangeEvent;
import no.ntnu.fp.model.events.ModelEvent;
import no.ntnu.fp.model.listeners.ModelListener;
import no.ntnu.fp.utils.MeetingRoomSchedule;
import no.ntnu.fp.utils.TimeInterval;

/**
 * @author H�kon Heggedal
 *
 */
@SuppressWarnings("serial")
public class Shared extends JPanel implements ModelListenerProvider{

	// tittel
	private JTextField textField;
	private JLabel lblTittel;

	// avtale eller m�te
	private ButtonGroup eventTypeButtonGroup;	
	private JRadioButton rdbtnAvtale;
	private JRadioButton rdbtnMte;

	// skriv ekstra beskrivelse
	private JLabel lblBeskrivelse;
	private JScrollPane scrollPane;
	private JTextArea descriptionTextArea;

	// velg tidspunkt
	private JLabel lblTidspunkt;
	private JComboBox endTime;
	private JComboBox startTime;
	private JComboBox date;

	// velg sted
	private ButtonGroup locationButtonGroup;
	private JRadioButton rdbtnSted;
	private JRadioButton rdbtnMterom;
	private JComboBox roomComboBox;
	private JTextField placeTextField;
	private MeetingRoomRenderer meetingRoomRenderer;
	private DefaultComboBoxModel roomComboBoxModel;

	// font-def s� det ikke trenger � defineres �rten ganger. ~C
	private Font lgType = new Font("Tahoma", Font.PLAIN, 14);
	private MeetingRoomSchedule schedule;
	private Calendar calendar;
	private Appointment appointment;

	/**
	 * lager panel.
	 * 
	 * panelet kan endres hvis ikke annet er valgt
	 */
	public Shared(Calendar calendar) {
		this.calendar = calendar;
		setLayout(null);
		setPreferredSize(new Dimension(350, 290));

		roomComboBoxModel = new DefaultComboBoxModel();

		eventTypeButtonGroup = new ButtonGroup();

		lblTittel = new JLabel("Tittel:");
		lblTittel.setFont(lgType);
		lblTittel.setBounds(10, 11, 40, 14);
		add(lblTittel);

		textField = new JTextField();
		textField.setBounds(60, 10, 170, 20);
		add(textField);
		textField.setColumns(10);

		rdbtnAvtale = new JRadioButton("Avtale");
		rdbtnAvtale.setToolTipText("Velg m�te eller avtale");
		eventTypeButtonGroup.add(rdbtnAvtale);
		rdbtnAvtale.setFont(lgType);
		rdbtnAvtale.setBounds(257, 7, 83, 23);
		add(rdbtnAvtale);

		rdbtnMte = new JRadioButton("M\u00F8te");
		rdbtnMte.setToolTipText("Velg m�te eller avtale");
		eventTypeButtonGroup.add(rdbtnMte);
		rdbtnMte.setFont(lgType);
		rdbtnMte.setBounds(257, 33, 83, 23);
		add(rdbtnMte);

		lblBeskrivelse = new JLabel("Beskrivelse:");
		lblBeskrivelse.setFont(lgType);
		lblBeskrivelse.setBounds(10, 53, 109, 14);
		add(lblBeskrivelse);

		scrollPane = new JScrollPane();
		scrollPane.setBounds(10, 78, 330, 94);
		add(scrollPane);

		descriptionTextArea = new JTextArea();
		descriptionTextArea.setLineWrap(true);
		scrollPane.setViewportView(descriptionTextArea);

		lblTidspunkt = new JLabel("Tidspunkt:");
		lblTidspunkt.setFont(lgType);
		lblTidspunkt.setBounds(10, 183, 70, 23);
		add(lblTidspunkt);

		date = new JComboBox();
		DateAndTimeListener dateAndTimeListener = new DateAndTimeListener();
		date.addActionListener(dateAndTimeListener);

		date.setRenderer(new DateRenderer());

		date.setBounds(90, 186, 77, 20);
		add(date);

		Time time = Time.valueOf("00:00:00");
		Calendar cal = new GregorianCalendar();
		cal.setTime(time);
		DefaultComboBoxModel startModel = new DefaultComboBoxModel(),
		endModel = new DefaultComboBoxModel();
		int date = cal.get(Calendar.DATE);
		do {
			startModel.addElement(new Time(cal.getTimeInMillis()).toString());
			endModel.addElement(new Time(cal.getTimeInMillis()).toString());
			cal.add(Calendar.MINUTE, 15);
		} while (date == cal.get(Calendar.DATE));

		startModel.setSelectedItem("12:00:00");
		endModel.setSelectedItem("13:00:00");

		startTime = new JComboBox(startModel);
		startTime.setBounds(177, 186, 77, 20);
		startTime.addActionListener(dateAndTimeListener);
		add(startTime);

		endTime = new JComboBox(endModel);
		endTime.setBounds(263, 186, 77, 20);
		endTime.addActionListener(dateAndTimeListener);
		add(endTime);


		locationButtonGroup = new ButtonGroup();

		rdbtnSted = new JRadioButton("Sted");
		rdbtnSted.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				if(rdbtnSted.isSelected()){
					placeTextField.setEnabled(true);
					placeTextField.setEditable(true);
					roomComboBox.setEnabled(false);	
					roomComboBox.setSelectedItem(null);
				}
			}
		});
		rdbtnSted.setToolTipText("Velg sted eller rom");
		rdbtnSted.setFont(lgType);
		locationButtonGroup.add(rdbtnSted);
		rdbtnSted.setBounds(10, 231, 85, 23);
		add(rdbtnSted);

		rdbtnMterom = new JRadioButton("M\u00F8terom");
		rdbtnMterom.addItemListener(new ItemListener() {
			public void itemStateChanged(ItemEvent arg0) {
				if(rdbtnMterom.isSelected()){
					// m�terom vises, sted vises ikke
					placeTextField.setEnabled(false);
					placeTextField.setEditable(false);
					setPlaceText("");
					roomComboBox.setEnabled(true);

					MeetingRoomsRequestedEvent evt = new MeetingRoomsRequestedEvent(Shared.this);
					EventDispatcher.dispatchEvent(evt);					
				}else{
					placeTextField.setEnabled(true);
					placeTextField.setEditable(true);
					roomComboBox.setEnabled(false);
				}
			}
		});
		rdbtnMterom.setToolTipText("Velg sted eller rom");
		rdbtnMterom.setFont(lgType);
		locationButtonGroup.add(rdbtnMterom);
		rdbtnMterom.setBounds(10, 257, 85, 23);
		add(rdbtnMterom);

		roomComboBoxModel = new DefaultComboBoxModel();
		roomComboBox = new JComboBox(roomComboBoxModel);
		roomComboBox.setEditable(false);
		roomComboBox.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent arg0) {
				rdbtnMterom.setSelected(true);

			}
		});
		roomComboBox.setBounds(124, 260, 216, 20);
		add(roomComboBox);

		meetingRoomRenderer = new MeetingRoomRenderer();
		roomComboBox.setRenderer(meetingRoomRenderer);

		placeTextField = new JTextField();
		placeTextField.addFocusListener(new FocusAdapter() {
			@Override
			public void focusGained(FocusEvent arg0) {
				rdbtnSted.setSelected(true);
			}
		});
		placeTextField.setBounds(124, 234, 216, 20);
		add(placeTextField);
		placeTextField.setColumns(10);

		rdbtnSted.setSelected(true);
	}

	public void setTitle(String title) {
		this.textField.setText(title);
	}

	public void setMeeting(boolean isMeeting) {
		this.rdbtnAvtale.setSelected(!isMeeting);
		this.rdbtnMte.setSelected(isMeeting);
	}

	public void setDescription(String description){
		this.descriptionTextArea.setText(description);
	}

	public void setDate(Date date) {
		this.date.getModel().setSelectedItem(date);
	}

	public void setStartTime(Time startTime) {
		//		this.startTime.setSelectedItem( startTime);
		this.startTime.getModel().setSelectedItem(startTime.toString());
	}

	public void setEndTime(Time endTime) {
		//		this.endTime.setSelectedItem( endTime);
		this.endTime.getModel().setSelectedItem(endTime.toString());
	}

	public void setPlaceSelected(boolean isPlace) {
		this.rdbtnSted.setSelected(isPlace);
	}

	public void setMeetingRoomSelected(boolean meetingroom) {
		this.rdbtnMterom.setSelected(meetingroom);
	}

	public void setMeetingRoom(MeetingRoom room) {
		roomComboBoxModel.setSelectedItem(room);
	}

	public void setPlaceText(String placeText) {
		this.placeTextField.setText(placeText);
	}
	public void setEditable(boolean bool)
	{
		textField.setEnabled(bool);
		rdbtnAvtale.setEnabled(bool);
		rdbtnMte.setEnabled(bool);
		descriptionTextArea.setEnabled(bool);
		date.setEnabled(bool);
		startTime.setEnabled(bool);
		endTime.setEnabled(bool);
		rdbtnSted.setEnabled(bool);
		rdbtnMterom.setEnabled(bool);
		roomComboBox.setEnabled(bool);
		placeTextField.setEnabled(bool);
	}

	// kan ikke velge m�te eller avtale
	public void disableType(){
		rdbtnAvtale.setEnabled(false);
		rdbtnMte.setEnabled(false);

		//		rdbtnAvtale.setToolTipText(null);
		//		rdbtnMte.setToolTipText(null);
	}



	/**
	 * @param schedule roomschedule
	 * @param interval timeinterval for the meeting
	 * 
	 * brukes n�r m�terom skal legges inn
	 */
	public void showMeetingRooms(MeetingRoomSchedule schedule, TimeInterval interval){ 
		this.schedule = schedule;

		schedule.setAppointment(this.appointment);
		
		roomComboBoxModel = new DefaultComboBoxModel(schedule.getAllMeetingRooms().toArray());

		meetingRoomRenderer.setMeetingRoomSchedule(schedule, interval);

		roomComboBox.setModel(roomComboBoxModel);

	}



	public boolean isMeetingSelected() {
		return rdbtnMte.isSelected();
	}

	public String getTitle() {
		return textField.getText();
	}

	public String getDescription() {
		String text = descriptionTextArea.getText();
		return (text == null ? "" : text);
	}

	public String getPlace() {
		String text = placeTextField.getText();
		return (text == null ? "" : text);
	}

	public MeetingRoom getMeetingRoom() {
		Object room = roomComboBox.getSelectedItem();
		return (room == null ? null : (MeetingRoom)room);
	}

	public MeetingRoomSchedule getSchedule() {
		return schedule;
	}

	public Date getDate() {
		return new Date(((java.util.Date)date.getSelectedItem()).getTime());
	}

	public void setDates() {
		DefaultComboBoxModel model = new DefaultComboBoxModel();
		Calendar cal = (Calendar)calendar.clone();
		
		int intervalSize = 30;
		cal.add(Calendar.DATE, -intervalSize);

		for (int i = 0; i < 2 * intervalSize; cal.add(Calendar.DATE, 1), i++) {
			model.addElement(cal.getTime());
		}
		model.setSelectedItem(calendar.getTime());
		date.setModel(model);
	}

	public Time getStartTime() {
		return Time.valueOf((String)startTime.getSelectedItem());
	}

	public Time getEndTime() {
		return Time.valueOf((String)endTime.getSelectedItem());
	}

	public void setRadioButtonListeners(ActionListener appListener,
			ActionListener meetingListener) {
		rdbtnAvtale.addActionListener(appListener);
		rdbtnMte.addActionListener(meetingListener);
	}

	public static class DateRenderer extends JLabel implements ListCellRenderer {

		@Override
		public Component getListCellRendererComponent(JList list, Object value,
				int index, boolean isSelected, boolean cellHasFocus) {
			if (isSelected) {
				setBackground(list.getSelectionBackground());
				setForeground(list.getSelectionForeground());
			} else {
				setBackground(list.getBackground());
				setForeground(list.getForeground());
			}

			java.util.Date date = (java.util.Date)value;

			DateFormat format = DateFormat.getDateInstance(DateFormat.SHORT, Locale.GERMAN);

			setText(format.format(date));

			return this;
		}
	}

	public class MeetingRoomsFetchedListener 
	implements ModelListener<DialogRoomScheduleChangeEvent> {

		@Override
		public void handleEvent(DialogRoomScheduleChangeEvent event) {
			showMeetingRooms(event.getSchedule(),
					new TimeInterval(new java.sql.Date(getDate().getTime()), 
							getStartTime(), getEndTime()));
			if(Shared.this.appointment != null){
				Shared.this.setMeetingRoom(Shared.this.appointment.getRoom());
			}
		}

	}

	private final class DateAndTimeListener implements ActionListener{
		@Override
		public void actionPerformed(ActionEvent e) {
			if(rdbtnMterom.isSelected()){
				meetingRoomRenderer.setMeetingRoomInterval(
						new TimeInterval(new java.sql.Date(getDate().getTime()), 
								getStartTime(), getEndTime()));
			}
		}
	}

	public void clear() {
		this.appointment = null;
		textField.setText("");
		descriptionTextArea.setText("");
		setMeeting(false);
		startTime.getModel().setSelectedItem("12:00:00");
		endTime.getModel().setSelectedItem("13:00:00");
		placeTextField.setText("");	
		rdbtnSted.setSelected(true);
		rdbtnAvtale.setEnabled(true);
		rdbtnMte.setEnabled(true);
		roomComboBoxModel.removeAllElements();

	}

	@Override
	public Map<Class<? extends ModelEvent>, ModelListener<?>> getEventListeners() {
		Map<Class<? extends ModelEvent>, ModelListener<?>> map =
			new HashMap<Class<? extends ModelEvent>, ModelListener<?>>();
		map.put(DialogRoomScheduleChangeEvent.class, new MeetingRoomsFetchedListener());
		return map;
	}

	public void setCurrentAppointment(Appointment appointment) {
		this.appointment = appointment;

	}


}
